import React from 'react';
import moment from 'moment';
import { Button, Icon, Checkbox, Tooltip } from 'antd';
import styles from './index.module.less';

const cellHeight = 32;
const getNumberOfDate = dateStr => moment(dateStr).hour() + moment(dateStr).minute() / 60;
const getFillItemStyle = (range, extra = {}) => {
    if (!range) return {};
    const [start, end] = range;
    const startValue = getNumberOfDate(start);
    const endValue = getNumberOfDate(end);
    return {
        width: '100%',
        top: startValue * cellHeight + 1,
        height: (endValue - startValue) * cellHeight - 1,
        background: '#EEF4FE',
        zIndex: 2,
        ...extra
    };
};
const checkIntersection = (a, b) => {
    const min = a[0] < b[0] ? a : b;
    const max = min === a ? b : a;
    return min[1] > max[0];
};
const getFormatTip = msg => `日程：${msg}`;
const btnStyle = { fontSize: 10 };
const hours = [...Array(24).keys()];

export default React.forwardRef(
    (
        {
            userList = [],
            range = [],
            onRangeChange = () => {},
            height = 'auto',
            rangeTitle = '',
            isValidTime = false,
            tableRef,
            autoScroll = false,
            isShowConflictControl = true // 员工档案的工作日程公用这个组件, 但是不需要显示右上角的 "靠前展示有冲突的人" 部分
        },
        ref
    ) => {
        const [sort, setSort] = React.useState(true);
        const popRef = React.useRef();
        // 理论上不能跨天
        const [startTimeStr, endTimeStr] = range;

        const startTime = moment(startTimeStr);
        const endTime = moment(endTimeStr);

        // 冗余过滤一下，后端数据没问题就不需要
        // const filterUserList = React.useMemo(() => {
        //     if (!isValidTime) return userList;
        //     return userList
        //         .map(user => ({
        //             ...user,
        //             rangeList: user?.rangeList.filter(
        //                 item => moment(item?.detailRange[0]).format('YYYY-MM-DD') === startTime.format('YYYY-MM-DD')
        //             )
        //         }))
        //         .filter(user => user.rangeList.length);
        // }, [userList, range, isValidTime]);

        // 后端返回得数据中有日期不对，但是属于每月/每日重复日程这类特殊数据数据
        const filterUserList = [...userList];

        // 获取排序以及冲突列表
        const getShowList = React.useCallback(() => {
            if (!isValidTime) return [filterUserList, []];
            const priorList = [];
            const restList = [];
            // 格式化一致，只考虑时间分钟
            const formatRule = 'HH:mm';
            const pivotRange = [startTime.format(formatRule), endTime.format(formatRule)];
            filterUserList.forEach(user => {
                // 区别单独的时间区间
                const existIntersectionList = user?.rangeList.filter(item =>
                    checkIntersection(pivotRange, [
                        moment(item.detailRange[0]).format(formatRule),
                        moment(item.detailRange[1]).format(formatRule)
                    ])
                );
                if (existIntersectionList.length) {
                    priorList.push({ ...user, conflict: existIntersectionList });
                } else {
                    restList.push(user);
                }
            });
            if (sort) {
                return [[...priorList, ...restList], priorList];
            }
            return [filterUserList, priorList];
        }, [filterUserList, startTime, endTime, sort, isValidTime]);

        const [sortList, conflictList] = getShowList();

        const getConflictMsg = React.useCallback(() => {
            if (conflictList.length) {
                return (
                    <div>
                        <Icon style={{ color: '#FF0000' }} type="info-circle" />{' '}
                        {conflictList.map(item => item.name).join('，')}日程有冲突
                    </div>
                );
            }
            return <div />;
        }, [conflictList]);

        const getConflictStyle = React.useCallback(
            (user, item) => {
                const conflictUser = conflictList.find(it => it.id === user.id);
                return conflictUser?.conflict.some(
                    it => it?.detailRange[0] === item[0] && it?.detailRange[1] === item[1]
                )
                    ? { background: '#FF7272' }
                    : {};
            },
            [conflictList]
        );

        const apiHandler = () => ({
            checkConflict: () => !!conflictList.length
        });

        // 为了不warning
        React.useImperativeHandle(ref, apiHandler);

        React.useImperativeHandle(tableRef, apiHandler);

        const { employeeCode: selfEmployeeCode } = JSON.parse(localStorage.getItem('user') ?? '{}');

        const renderScheduleDetail = React.useCallback(() => {
            if (sortList.length) {
                return sortList.map(user => {
                    const { id } = user;
                    const isSelf = id === selfEmployeeCode;

                    return (
                        <div key={user.id} className={styles.column}>
                            {hours.map(hour => (
                                <div key={hour} className={styles.cell} />
                            ))}
                            {user.rangeList.map(item => (
                                <Tooltip
                                    key={item.id}
                                    placement="left"
                                    // title={getFormatTip(item.title)}
                                    title={isSelf ? item.title : '该时间段已被占用'}
                                    getPopupContainer={() => popRef.current ?? document.body}
                                >
                                    <div
                                        className={styles.fillItem}
                                        style={getFillItemStyle(
                                            item.detailRange,
                                            getConflictStyle(user, item.detailRange)
                                        )}
                                    />
                                </Tooltip>
                            ))}
                        </div>
                    );
                });
            }
            return (
                <div className={styles.column}>
                    {hours.map(hour => (
                        <div key={hour} className={styles.cell} />
                    ))}
                </div>
            );
        }, [sortList, selfEmployeeCode, getConflictStyle]);

        const handleDateChange = React.useCallback(
            val => {
                onRangeChange([
                    startTime.add(val, 'day').format('YYYY-MM-DD HH:mm'),
                    endTime.add(val, 'day').format('YYYY-MM-DD HH:mm')
                ]);
            },
            [onRangeChange, startTime, endTime]
        );

        const handleDateReset = React.useCallback(() => {
            onRangeChange([
                moment()
                    .hour(startTime.hour())
                    .minute(startTime.minute()),
                moment()
                    .hour(endTime.hour())
                    .minute(endTime.minute())
            ]);
        }, [onRangeChange, startTime, endTime]);

        React.useEffect(() => {
            if (!isValidTime || !autoScroll) return;
            const isScrollAble = popRef.current.offsetHeight < popRef.current.scrollHeight;
            if (isScrollAble) {
                popRef.current.scrollTop = getNumberOfDate(startTime) * cellHeight;
            }
        }, [startTime, endTime, isValidTime, autoScroll]);

        return (
            <div className={styles.wrap}>
                <div className={styles.top}>
                    <Button className={styles.todayBtn} onClick={handleDateReset}>
                        今天
                    </Button>
                    <div>
                        <Icon type="left" {...btnStyle} onClick={() => handleDateChange(-1)} />
                        <span className={styles.dateInfo}>{startTime.format('YYYY-MM-DD dddd')}</span>
                        <Icon type="right" {...btnStyle} onClick={() => handleDateChange(1)} />
                    </div>
                </div>
                <div className={styles.main} style={{ height }} ref={popRef}>
                    {isShowConflictControl && (
                        <div className={styles.tip}>
                            {getConflictMsg()}
                            <div>
                                <Checkbox checked={sort} onChange={e => setSort(e.target.checked)} />
                                <span style={{ paddingLeft: 6 }}>靠前展示有冲突的人</span>
                            </div>
                        </div>
                    )}
                    <div className={styles.context}>
                        <div className={styles.hours}>
                            <div className={styles.hourItem}></div>
                            <div className={styles.hourDegree}>
                                {hours.map(hour => (
                                    <div className={styles.hourItem} key={hour}>
                                        {`0${hour}:00`.substr(-5)}
                                    </div>
                                ))}
                            </div>
                        </div>
                        <div className={styles.detail}>
                            <div className={styles.detailUser} style={isShowConflictControl ? null : { top: '0px', borderTop: '1px solid #d9d9d9' }}>
                                {sortList.map(item => (
                                    <div key={item.id} className={styles.column}>
                                        <div className={styles.user}>{item.name}</div>
                                    </div>
                                ))}
                            </div>
                            <div className={styles.detailColumn}>
                                {renderScheduleDetail()}
                                {isValidTime && (
                                    <Tooltip
                                        placement="left"
                                        title={getFormatTip(rangeTitle)}
                                        getPopupContainer={() => popRef.current ?? document.body}
                                    >
                                        <div
                                            className={styles.fillItem}
                                            style={{
                                                ...getFillItemStyle(range, {
                                                    background: '#FFF2E2',
                                                    zIndex: 1,
                                                    left: 1
                                                })
                                            }}
                                        />
                                    </Tooltip>
                                )}
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        );
    }
);
